package ch.myDungeons.io;

import java.util.ArrayList;

import ch.myDungeons.game.Inventory.BagSlot;
import ch.myDungeons.gameObjects.Armor;
import ch.myDungeons.gameObjects.Item;
import ch.myDungeons.gameObjects.Potion;
import ch.myDungeons.gameObjects.Weapon;


/**
 * A static class to generate items from templates
 * @author Grii
 *
 */
public class ItemGenerator {
	
	static{
		loadData();
	}
	
	/** All the data for the weapons
	 * 0 weaponNames <> 1 weaponDamageDice <> 2 weaponDamageBonus <> 3 weaponValue
	 */
	private static Object[][] weaponData;
	
	/** All the data for the armors
	 * 0 armorNames <> 1 armorBonus <> 2 armorValue
	 */
	private static Object[][] armorData;

	/** Loads the data files for the weapons and armors */
	public static void loadData(){
		String[] weapons = IOStream.loadWeaponDataFile();
		weaponData = new Object[weapons.length][4];
		for (int i = 0; i < weapons.length; i++) {
			weapons[i] = weapons[i].replaceAll(" <>", "<>");
			weapons[i] = weapons[i].replaceAll("<> ", "<>");
			String[] tmpWeaponData = weapons[i].split("<>");
			if (tmpWeaponData.length == 4) {
				weaponData[i][0] = tmpWeaponData[0];
				weaponData[i][1] = Integer.parseInt(tmpWeaponData[1]);
				weaponData[i][2] = Integer.parseInt(tmpWeaponData[2]);
				weaponData[i][3] = Integer.parseInt(tmpWeaponData[3]);
			} else {
				weaponData[i][0] = "potato";
				weaponData[i][1] = 0;
				weaponData[i][2] = 1;
				weaponData[i][3] = 0;
			}
		}
		
		String[] armors = IOStream.loadArmorDataFile();
		armorData = new Object[armors.length][3];
		for (int i = 0; i < armors.length; i++) {
			armors[i] = armors[i].replaceAll(" <>", "<>");
			armors[i] = armors[i].replaceAll("<> ", "<>");
			String[] tmpArmorData = armors[i].split("<>");
			if (tmpArmorData.length == 3) {
				armorData[i][0] = tmpArmorData[0];
				armorData[i][1] = Integer.parseInt(tmpArmorData[1]);
				armorData[i][2] = Integer.parseInt(tmpArmorData[2]);
			} else {
				armorData[i][0] = "potato";
				armorData[i][1] = 0;
				armorData[i][2] = 1;
			}
		}
	}
	
	
	/** Returns an armor with a random name and armor bonus */
	public static Armor createArmorFromRating(int rating){
		int armorValue = (int)(rating/2.0 + rating*1.0*Math.random());
		ArrayList<Integer> indexList = new ArrayList<Integer>();
		int currentMax = 0;
		for (int i = 0; i < armorData.length; i++) {
			if (armorValue >= (Integer)armorData[i][2]) {
				if (currentMax <= (Integer)armorData[i][2]) {
					indexList.removeAll(indexList);
					currentMax = (Integer)armorData[i][2];
				}
				indexList.add(i);
			}
		}
		return createArmor(indexList.get((int)(indexList.size()*Math.random())));
	}
	
	/** Returns an armor with a fixed name and armor bonus */
	public static Armor createArmor(int armorType){
		armorType = armorType%armorData.length;
		Armor armor = new Armor((String)armorData[armorType][0], (Integer)armorData[armorType][1]);
		return armor;
	}
	
	/** Returns a weapon with a random name and weapon bonus */
	public static Weapon createWeaponFromRating(int rating){
		int weaponValue = (int)(rating/2.0 + rating*1.0*Math.random());
		ArrayList<Integer> indexList = new ArrayList<Integer>();
		int currentMax = 0;
		for (int i = 0; i < weaponData.length; i++) {
			if (weaponValue >= (Integer)weaponData[i][3]) {
				if (currentMax <= (Integer)weaponData[i][3]) {
					indexList.removeAll(indexList);
					currentMax = (Integer)weaponData[i][3];
				}
				indexList.add(i);
			}
		}
		return createWeapon(indexList.get((int)(indexList.size()*Math.random())));
	}
	
	/** Returns a weapon with a fixed name and weapon bonus */
	public static Weapon createWeapon(int weaponType){
		weaponType = weaponType%weaponData.length;
		Weapon weapon = new Weapon((String)weaponData[weaponType][0], (Integer)weaponData[weaponType][2], (Integer)weaponData[weaponType][1]);
		return weapon;
	}
	
	
	/** Returns an item with the name specified */
	public static Item createItemFromName(String itemName){
		Item item = null;
		boolean foundItem = false;
		for (int i = 0; i < armorData.length && !foundItem; i++) {
			if (((String)armorData[i][0]).equals(itemName)) {
				item = createArmor(i);
				foundItem = true;
			}
		}
		for (int i = 0; i < weaponData.length && !foundItem; i++) {
			if (((String)weaponData[i][0]).equals(itemName)) {
				item = createWeapon(i);
				foundItem = true;
			}
		}
		return item;
	}
	
	/** Returns a potion  */
	public static BagSlot createPotion(int count){
		BagSlot potion = new BagSlot(new Potion.HealthPotion(""), count);
		return potion;
	}

	/** Loads an array of items from a string 
	 * @deprecated */
	@Deprecated
	public static BagSlot[] createItemsFormString(String itemsString) {
		String[] dataStrings = itemsString.split("<ITEM>");
		BagSlot[] loadedItems = new BagSlot[]{};
		if (dataStrings.length > 0) {
			loadedItems = new BagSlot[dataStrings.length-1];
		}
		for (int i = 0; i < loadedItems.length; i++) {
			loadedItems[i] = createItemFormString(dataStrings[i+1]);
		}
		return loadedItems;
	}
	
	/** Loads a single item from a string 
	 * @deprecated */
	@Deprecated
	public static BagSlot createItemFormString(String itemsString) {
		String[] dataStrings = itemsString.split("<ITEMINFO>");
		BagSlot loadedItem = null;
		
		String name = dataStrings[1];
		int count = Integer.parseInt(dataStrings[0]);
		String itemType = dataStrings[2];
		
		if (itemType.equals("weapon")) {
			int attackDamageBonus = Integer.parseInt(dataStrings[3]);
			int attackDamageDice = Integer.parseInt(dataStrings[4]);
			loadedItem = new BagSlot(new Weapon(name, attackDamageBonus, attackDamageDice), 1);
		} 
		else if (itemType.equals("armor")) {
			int armorBonus = Integer.parseInt(dataStrings[3]);
			loadedItem = new BagSlot(new Armor(name, armorBonus), 1);
		}
		else if (itemType.equals("healthpotion")) {
			int healthRestore = Integer.parseInt(dataStrings[3]);
			loadedItem = new BagSlot(new Potion.HealthPotion(name), 1);
			loadedItem.getItem().name = name;
			((Potion.HealthPotion)loadedItem.getItem()).healthRestore = healthRestore;
		}
		
		loadedItem.setCount(count);
		return loadedItem;
	}
}
